#include "stm32f10x.h"                  // Device header
#include "led.h"
#include "PWM.h"
#include "Motor.h"
/**
* @brief  通过GPIO引脚使用通用定时器输出PWM波形初始化。不同的输出引脚需要用到不同的输出比较通道。结构体初始化的某些成员只在高级定时器里有用，故先使
					用了TIM_OCStructInit进行赋初值，然后仅修改了通用定时器会使用到的成员，防止以后需要使用高级定时器时出现错误。TIM2计时器的OC1引脚是复用于A0
					引脚的、OC2引脚是复用于A1引脚的，以此类推。可以通过配置AFIO进行重映射，使用其他引脚
	* @param  RCC_APB2Periph_GPIO：将会用于传入外部触发信号的GPIO引脚的时钟
  * @param  GPIOx: 哪一片GPIO（参照GPIO_Init）
  * @param  pin：一片GPIO中具体哪个引脚，用于输出PWM（参照结构体GPIO_InitTypeDef中的定义）（需要与参数Init_Function_Index对应）
	* @param  mode：输入模式。GPIO_Mode_AF_PP表示复用推挽输出，输出控制权转移给片上外设，即TIM2的CH1通道
	* @param  RCC_APB1Periph: 最常用的通用定时器（可能只有部分，如TIM2）是APB1总线的外设
  * @param  TIMx: 选择时基单元的时钟，如果与上面的参数相对应就是使用的内部时钟
	* @param  TIM_ClockDivision：滤波器采样频率分频值。设置得越高，频率越低，采样点数越多，滤波效果越好，但
						信号延迟也会更大。根据需要选择合适值，若输入的波形可以确保其比较稳定就可以随便配置。参见
						TIM_Clock_Division_CKD
	* @param  TIM_CounterMode：计数模式，分向上、向下和中央对齐三种。参见TIM_Counter_Mode
	* @param  TIM_Period：计时器时钟，即ARR
	* @param  TIM_Prescaler：预分频器时钟，即PSC
	
	以上两个参数共同决定定时频率，计算公式为定时频率72MHz/(TIM_Period+1)/(TIM_Prescaler+1)
	
	* @param  TIM_RepetitionCounter：配置重复计数器。这个是只有高级计数器才有的，用不到的话直接输入一个0就行
	* @param  TIM_OCMode：输出比较模式，参见TIM_Output_Compare_and_PWM_modes
	* @param  TIM_OCPolarity：输出比较极性，参见TIM_Output_Compare_Polarity
	* @param  TIM_Pulse：指定Pluse的值，会被加载到capture compare register，即CCR，参见TIM_OCInitTypeDef

	PWM占空比：CCR/(ARR+1), 分辨率：1/(ARR+1)

  * @param  Init_Function_Index：选择需要用于初始化的通道的函数，函数列表参见本文件第5行起的数组Init_Function
  * @param  pin_ctrl：用于控制电机方向的引脚，一般是成对或起来输入
	* @retval None
*/
void Motor_Init(uint32_t RCC_APB2Periph_GPIO, GPIO_TypeDef* GPIOx, uint16_t pin, GPIOMode_TypeDef mode, uint32_t RCC_APB1Periph, 
	TIM_TypeDef* TIMx, uint16_t TIM_ClockDivision, uint16_t TIM_CounterMode, uint16_t TIM_Period, uint16_t TIM_Prescaler, uint8_t 
	TIM_RepetitionCounter, uint16_t TIM_OCMode, uint16_t TIM_OCPolarity, uint16_t TIM_Pulse, uint8_t Init_Function_Index, uint16_t pin_ctrl)
{
	PWM_Init(RCC_APB2Periph_GPIO, GPIOx, pin, mode, RCC_APB1Periph, TIMx, TIM_ClockDivision, TIM_CounterMode, TIM_Period, TIM_Prescaler, 
	TIM_RepetitionCounter, TIM_OCMode, TIM_OCPolarity, TIM_Pulse, Init_Function_Index);
	gpio_Init(RCC_APB2Periph_GPIO, GPIOx, pin_ctrl, GPIO_Mode_Out_PP);
}

/**
* @brief  通过改变CCR的值来改变波形占空比，进而调节电机转速
* @param  Speed：电机速度，可为正或负，分别使得电机往两个方向旋转，范围为-100到100
	* @param  GPIOx：正、反转控制引脚所在的GPIO
	* @param  pin_pluse、pin_minus：正、反转控制引脚。接线得当的情况下Speed为正时正转，否则为负时才正转
	* @param  TIMx: 选择时基单元的时钟。
	* @param  Duty_Change_Function_Index：选择需要与所用通道对应的、用于修改参数的函数，函数列表参见本文件第10行起的数组Duty_Change_Function
  * @retval None
	* @retval None
*/
void Motor_SetSpeed(int8_t Speed, GPIO_TypeDef* GPIOx, uint16_t pin_pluse, uint16_t pin_minus, TIM_TypeDef* TIMx, uint8_t Duty_Change_Function_Index)
{
	if (Speed >= 0)
	{
		GPIO_SetBits(GPIOx, pin_pluse);
		GPIO_ResetBits(GPIOx, pin_minus);
		Duty_Change(TIMx, Speed, Duty_Change_Function_Index);
	}
	else
	{
		GPIO_SetBits(GPIOx, pin_minus);
		GPIO_ResetBits(GPIOx, pin_pluse);
		Duty_Change(TIMx, -Speed, Duty_Change_Function_Index);
	}
}
